﻿using LightCAD.Core.Element3d;
using LightCAD.MathLib;
using LightCAD.Three;
using System;
using System.Collections.Generic;
using static System.Windows.Forms.DataFormats;

namespace QdArch
{
    public class RoofAttribute : CptAttribute
    {
        public RoofAttribute(string category, string subCategorys) : base(category, subCategorys)
        {
        }
        public const string BuiltinUuid = "{f816fa4a-c4a1-461f-908f-62302959b28e}";

        public override LcComponentDefinition GetBuiltinCpt(string subCategory)
        {
            return null;
        }
    }
    [RoofAttribute("屋顶", "坡屋顶")]
    public class QdRoofRef : LcComponentDefinition
    {
        static QdRoofRef()
        {
            CptTypeParamsDef<QdRoofRef>.ParamsDef = new ParameterSetDefinition {
                new ParameterDefinition { DataType = LcDataType.String, Name = "MaterialId", DisplayName = "材质", },
             new ParameterDefinition { DataType = LcDataType.String, Name = "SectionId", DisplayName = "截面", }
            };
        }
        public QdRoofRef()
        {
            this.TypeParameters = new LcParameterSet(CptTypeParamsDef<QdRoofRef>.ParamsDef);
        }
        public QdRoofRef(string uuid, string name, string subCategory, string sectionId) : base(uuid, name, "屋顶", subCategory, new LcParameterSet(CptTypeParamsDef<QdRoofRef>.ParamsDef))
        {
            this.TypeParameters.SetValue("SectionId", sectionId);
            this.Parameters = new ParameterSetDefinition()
            {
                  new ParameterDefinition { Name = "SectionType", DataType = LcDataType.Int } ,
                    new ParameterDefinition { Name = "FasciaDepth", DataType = LcDataType.Double } ,
                    new ParameterDefinition { Name = "SlabThickness", DataType = LcDataType.Double } ,
                    new ParameterDefinition { Name = "Angle", DataType = LcDataType.Double } ,
                     new ParameterDefinition { Name = "Elevation", DataType = LcDataType.Double } ,

            };
            this.Curve2dProvider = new Curve2dProvider("屋顶")
            {
                GetCurve2dsFunc = (pset) =>
                {
                    var sectionId = this.TypeParameters.GetValue<string>("SectionId");
                    var curve2ds = new List<Curve2d>();
                    if (SectionManager.Sections.TryGetValue(sectionId, out var section))
                    {
                        curve2ds = section.Segments.Clone();
                    }
                    return new Curve2dGroupCollection() { new Curve2dGroup()
                        {
                            Curve2ds = curve2ds.ToListEx()
                        }
                    };
                } 
            };
            var mat = MaterialManager.GetMaterial(MaterialManager.DefaultUuid);
            this.Solid3dProvider = new Solid3dProvider("屋顶")
            {
                AssignMaterialsFunc = (c, s) => {
                    return new LcMaterial[] { mat };
                }
            };
        }
    }

    public class QdRoofInstance : LcComponentInstance
    {
        //橼截面类型，0:垂直截面，1:垂直双界面，2:正方形
        public static Dictionary<int, string> SectionEnums = new Dictionary<int, string> { { 0, "垂直截面" }, { 1, "垂直双截面" }, { 2, "正方形双截面" } };
        public int SectionType { get => Parameters.GetValue<int>("SectionType"); set => Set("SectionType", value); }
        public double FasciaDepth { get => Parameters.GetValue<double>("FasciaDepth"); set => Set("FasciaDepth", value); }
        public double SlabThickness { get => Parameters.GetValue<double>("SlabThickness"); set => Set("SlabThickness", value); }
        public double Angle { get => Parameters.GetValue<double>("Angle"); set => Set("Angle", value); }
        public double Elevation { get => Parameters.GetValue<double>("Elevation"); set => Set("Elevation", value); }

        public QdRoofInstance(QdRoofRef roof) : base(roof)
        {
            this.Type = ArchElementType.Roof;
        }

 
        //public override bool IntersectWithBox(Polygon2d testPoly, List<RefChildElement> intersectChildren = null)
        //{
        //    Box2 thisBox = this.BoundingBox;
        //    if (!(thisBox.IntersectsBox(testPoly.BoundingBox) || thisBox.ContainsBox(testPoly.BoundingBox)))
        //    {
        //        return false;
        //    }
            
        //    return false;
        //}
        //public override bool IncludedByBox(Polygon2d testPoly, List<RefChildElement> includedChildren = null)
        //{
        //    Box2 thisBox = this.BoundingBox;
        //    if (!testPoly.BoundingBox.ContainsBox(thisBox))
        //    {
        //        return false;
        //    }
        //    return true;
        //}
        public void Set(string name, object val)
        {
            OnPropertyChangedBefore(name, this.Parameters[name], val);
            this.Parameters.SetValue(name, val);
            OnPropertyChangedAfter(name, this.Parameters[name], val);
        }
        public override LcElement Clone()
        {
            var clone = new QdRoofInstance(this.Definition as QdRoofRef);
            clone.Copy(this);
            clone.Initilize(this.Document);
            return clone;
        }
        //public override Box2 GetBoundingBox()
        //{
        //    if (this.Parameters == null || this.Parameters.Values.Length == 0)
        //    {
        //        return Box2.Empty;
        //    }

        //    return Box2.Empty;

        //}
        //public override Box2 GetBoundingBox(Matrix3 matrix)
        //{
        //    if (this.Parameters == null || this.Parameters.Values.Length == 0)
        //    {
        //        return Box2.Empty;
        //    }

        //    return Box2.Empty;
        //}
        public override void Copy(LcElement src)
        {
            base.Copy(src);
            var RoofRef = (QdRoofInstance)src;
            this.Parameters = RoofRef.Parameters.Definition.New();
            this.Definition = RoofRef.Definition;
            var count = RoofRef.Parameters.Values.Count();
            for (int i = 0; i < count; i++)
            {
                this.Parameters[i] = RoofRef.Parameters[i];
            }

        }

        public override void WriteProperties(Utf8JsonWriter writer, JsonSerializerOptions soptions)
        {
            base.WriteProperties(writer, soptions);
        }

        public override void ReadProperties(ref JsonElement jele)
        {
            base.ReadProperties(ref jele);
        }
    }
}
